package com.telenav;

import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.event.InputEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map.Entry;
import javax.imageio.ImageIO;

import org.sf.feeling.swt.win32.extension.registry.RegistryKey;
import org.sf.feeling.swt.win32.extension.registry.RootKey;

public class TTLinkCrack implements TTCrack {

	public static int DIFF_THRESHOULD = 24;
	public int WHITE_COUNT = 86;
	public int BLACK_COUNT = 110;
	public int saved_mpx1 = -1;
	public int saved_mpy1 = -1;
	public int saved_mpx2 = -1;
	public int saved_mpy2 = -1;
	public int RESOLUTION_W = 1600;
	public org.eclipse.swt.graphics.Rectangle wndRect = null;

	public static boolean DEBUG = false;

	/**
	 * @param args
	 * @throws Exception 
	 */
	public static void main(String[] args) throws Exception {
		BufferedImage bufferedImage = ImageIO.read(new File("E:\\tt\\capturelink1.png"));
		new TTLinkCrack().crackMove(null, null, bufferedImage);
		//new TTLinkCrack().findRoute();
		//		new TTLinkCrack().findOneRouteTest();
	}

	public void crackMove(Robot robot, Dimension scrSize, BufferedImage bufferedImageFile) throws Exception {
		BufferedImage origBufferedImage = null;
		try {
			long lasttime = 0;
			if (DEBUG) {
				RegistryKey registryKey = new RegistryKey(RootKey.HKEY_LOCAL_MACHINE, "SOFTWARE\\BlueStacks\\Guests\\Android\\FrameBuffer\\0");
				int width = (Integer) registryKey.getValue("Width").getData();
				System.out.println(width);
				RESOLUTION_W = width;
				WHITE_COUNT = WHITE_COUNT * width / 1600;
				BLACK_COUNT = BLACK_COUNT * width / 1600;
				//							saved_mpx1 = 235;
				//							saved_mpy1 = 80;
				//							saved_mpx2 = 787;
				//							saved_mpy2 = 509;
				wndRect = new org.eclipse.swt.graphics.Rectangle(625, 283 + 22, 1030, 652 - 22);
				//			wndRect = new org.eclipse.swt.graphics.Rectangle(144, 46 + 22, 1606, 956 - 22);
				lasttime = System.currentTimeMillis();
			}
			System.out.println(WHITE_COUNT + "," + BLACK_COUNT + "," + wndRect);
			if (wndRect == null) {
				System.err.println("Failed to get window's rectanger.");
				return;
			}
			if (bufferedImageFile == null) {
				origBufferedImage = robot.createScreenCapture(new Rectangle(scrSize));
			} else {
				origBufferedImage = bufferedImageFile;
			}
			//		ImageIO.write(bufferedImage, "BMP", new File("E:\\tt\\capture.bmp"));

			BufferedImage pTo = new BufferedImage(origBufferedImage.getWidth(), origBufferedImage.getHeight(), origBufferedImage.getType());
			ImgProcess.Threshold(origBufferedImage, pTo, 200);
			BufferedImage bufferedImage = ImgProcess.copyImage(pTo);
			if (DEBUG) {
				ImageIO.write(bufferedImage, "BMP", new File("E:\\tt\\outlink.bmp"));
			}

			int x1 = wndRect.x;
			int x2 = x1 + wndRect.width;
			int y1 = wndRect.y;
			int y2 = y1 + wndRect.height;

			int width = x2 - x1;
			int height = y2 - y1;
			BufferedImage imageOut = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
			for (int j = 0; j < height; j++) {
				for (int i = 0; i < width; i++) {
					int gray = ImgProcess.GetGray(bufferedImage, x1 + i, y1 + j);
					imageOut.setRGB(i, j, ImgProcess.getRGB(gray, gray, gray));
				}
			}
			if (DEBUG) {
				ImageIO.write(imageOut, "BMP", new File("E:\\tt\\out.bmp"));
				System.out.println((System.currentTimeMillis() - lasttime) + "ms");
				lasttime = System.currentTimeMillis();
			}
			ArrayList<Rectangle> rects = new ArrayList<Rectangle>();

			int a1 = 0;
			int last_a1 = 0;
			Point sa1;
			int b1 = 0;
			for (int j = 0; j < height; j++) {
				for (int i = 0; i < width; i++) {
					int whiteCount = 0;
					int gray = ImgProcess.GetGray(imageOut, i, j);
					if (gray > 128) {
						int k = i;
						for (; k < i + WHITE_COUNT * 2 && k < width; k++) {
							gray = ImgProcess.GetGray(imageOut, k, j);
							if (gray > 128) {
								whiteCount++;
							} else {
								k--;
								break;
							}
						}
						if (whiteCount > WHITE_COUNT * 0.8) {
							a1 = whiteCount;
							if (a1 < last_a1) {
								a1 = last_a1;
							}
							sa1 = new Point(i, j);
							whiteCount = 0;
							int t = j;
							for (; t < j + WHITE_COUNT * 2 && t < height && k - a1 > 0; t++) {
								if (t > height - 1) {
									break;
								}
								gray = ImgProcess.GetGray(imageOut, k - a1, t);
								if (gray > 128 || (whiteCount > WHITE_COUNT / 2 && ImgProcess.GetGray(imageOut, k + 2, t) > 128)) {
									whiteCount++;
								} else {
									t--;
									break;
								}
							}
							if (whiteCount > WHITE_COUNT) {
								if (b1 == 0) {
									b1 = whiteCount;
								}
								whiteCount = 0;
								for (int m = k - a1; m < k; m++) {
									gray = ImgProcess.GetGray(imageOut, m, t - 4);
									if (gray > 128) {
										whiteCount++;
									} else {
										m++;
										break;
									}
								}
								if (whiteCount > WHITE_COUNT / 2) {
									Rectangle rect = new Rectangle(sa1, new Dimension(a1, b1));
									rects.add(rect);
									i = i + a1 + 5;
									last_a1 = a1;
									a1 = 0;
								} else {
									b1 = 0;
								}
							}
						}
					}
				}
				if (b1 != 0) {
					j = j + b1 + 3;
					b1 = 0;
				}
			}

			System.out.println(rects);
			System.out.println(rects.size());
			ArrayList<LinkBlock> linkBlocks = new ArrayList<LinkBlock>();
			int mpx1 = Integer.MAX_VALUE;
			int mpy1 = Integer.MAX_VALUE;
			int mpx2 = Integer.MIN_VALUE;
			int mpy2 = Integer.MIN_VALUE;
			for (Rectangle r : rects) {
				if (r.x < mpx1) {
					mpx1 = r.x;
				}
				if (r.x > mpx2) {
					mpx2 = r.x;
				}
				if (r.y < mpy1) {
					mpy1 = r.y;
				}
				if (r.y > mpy2) {
					mpy2 = r.y;
				}
			}
			if (mpx1 == Integer.MAX_VALUE || mpy1 == Integer.MAX_VALUE || mpx2 == Integer.MIN_VALUE || mpy2 == Integer.MIN_VALUE) {
				return;
			}
			int blockWidth = rects.get(0).width;
			int blockHeight = rects.get(0).height;
			int mx = (mpx2 - mpx1) / blockWidth;
			int my = (mpy2 - mpy1) / blockHeight;
			System.out.println("mpx1=" + mpx1 + ",mpy1=" + mpy1 + ",mpx2=" + mpx2 + ",mpy2=" + mpy2 + ",mx=" + mx + ",my=" + my);

			System.out.println("saved_mpx1=" + saved_mpx1 + ",saved_mpy1=" + saved_mpy1 + ",saved_mpx2=" + saved_mpx2 + ",saved_mpy2=" + saved_mpy2);
			if (saved_mpx1 != -1 && saved_mpy1 != -1 && saved_mpx2 != -1 && saved_mpy2 != -1) {
				try {
					int count = (saved_mpx2 - saved_mpx1) / blockWidth;
					int avgBlockWidth = (saved_mpx2 - saved_mpx1) / count;
					count = (saved_mpy2 - saved_mpy1) / blockHeight;
					int avgBlockHeight = (saved_mpy2 - saved_mpy1) / count;
					for (int tx = saved_mpx1 + avgBlockWidth / 2; tx < saved_mpx2 + avgBlockWidth; tx += avgBlockWidth) {
						for (int ty = saved_mpy1 + avgBlockHeight / 2; ty < saved_mpy2 + avgBlockHeight; ty += avgBlockHeight) {
							boolean isContain = false;
							for (Rectangle r : rects) {
								if (r.x < tx && r.x + r.width > tx && r.y < ty && r.y + r.height > ty) {
									isContain = true;
								}
							}
							if (!isContain) {
								int j = ty - avgBlockHeight / 2 + 10;
								int whiteCount = 0;
								for (int i = tx - avgBlockWidth / 2; i < tx + avgBlockWidth / 2; i++) {
									int gray = ImgProcess.GetGray(imageOut, i, j);
									if (gray > 128) {
										whiteCount++;
									}
								}
								if (whiteCount > WHITE_COUNT / 2) {
									Rectangle rect = new Rectangle(new Point(tx - avgBlockWidth / 2, ty - avgBlockHeight / 2), new Dimension(blockWidth,
											blockHeight));
									rects.add(rect);
								}
							}
						}
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			if (mpx2 > saved_mpx2) {
				saved_mpx1 = mpx1;
				saved_mpx2 = mpx2;
				saved_mpy1 = mpy1;
				saved_mpy2 = mpy2;
			}

			for (Rectangle r : rects) {
				LinkBlock linkBlock = new LinkBlock(r);
				linkBlocks.add(linkBlock);
				int r1 = (int) (x1 + r.x + r.width * 0.4);
				int c1 = (int) (y1 + r.y + r.height * 0.4);
				int r2 = (int) (x1 + r.x + r.width * 0.5);
				int c2 = (int) (y1 + r.y + r.height * 0.5);
				int r3 = (int) (x1 + r.x + r.width * 0.6);
				int c3 = (int) (y1 + r.y + r.height * 0.6);
				int pixel = origBufferedImage.getRGB(r1, c1);
				linkBlock.calPoints.add(new RGB(ImgProcess.GetRValue(pixel), ImgProcess.GetGValue(pixel), ImgProcess.GetBValue(pixel)));
				pixel = origBufferedImage.getRGB(r1, c2);
				linkBlock.calPoints.add(new RGB(ImgProcess.GetRValue(pixel), ImgProcess.GetGValue(pixel), ImgProcess.GetBValue(pixel)));
				pixel = origBufferedImage.getRGB(r1, c3);
				linkBlock.calPoints.add(new RGB(ImgProcess.GetRValue(pixel), ImgProcess.GetGValue(pixel), ImgProcess.GetBValue(pixel)));
				pixel = origBufferedImage.getRGB(r2, c1);
				linkBlock.calPoints.add(new RGB(ImgProcess.GetRValue(pixel), ImgProcess.GetGValue(pixel), ImgProcess.GetBValue(pixel)));
				pixel = origBufferedImage.getRGB(r2, c2);
				linkBlock.calPoints.add(new RGB(ImgProcess.GetRValue(pixel), ImgProcess.GetGValue(pixel), ImgProcess.GetBValue(pixel)));
				pixel = origBufferedImage.getRGB(r2, c3);
				linkBlock.calPoints.add(new RGB(ImgProcess.GetRValue(pixel), ImgProcess.GetGValue(pixel), ImgProcess.GetBValue(pixel)));
				pixel = origBufferedImage.getRGB(r3, c1);
				linkBlock.calPoints.add(new RGB(ImgProcess.GetRValue(pixel), ImgProcess.GetGValue(pixel), ImgProcess.GetBValue(pixel)));
				pixel = origBufferedImage.getRGB(r3, c2);
				linkBlock.calPoints.add(new RGB(ImgProcess.GetRValue(pixel), ImgProcess.GetGValue(pixel), ImgProcess.GetBValue(pixel)));
				pixel = origBufferedImage.getRGB(r3, c3);
				linkBlock.calPoints.add(new RGB(ImgProcess.GetRValue(pixel), ImgProcess.GetGValue(pixel), ImgProcess.GetBValue(pixel)));
				linkBlock.x = (r.x - mpx1) / r.width;
				linkBlock.y = (r.y - mpy1) / r.height;

				for (int j = y1 + r.y; j < y1 + r.y + r.height + 1; j++) {
					for (int i = x1 + r.x; i < x1 + r.x + r.width + 1; i++) {
						if (i > x1 + r.x && i < x1 + r.x + r.width && j > y1 + r.y && j < y1 + r.y + r.height) {
							continue;
						}
						bufferedImage.setRGB(i, j, ImgProcess.getRGB(255, 0, 0));
					}
				}
			}
			if (DEBUG) {
				ImageIO.write(bufferedImage, "BMP", new File("E:\\tt\\out4.bmp"));
				System.out.println((System.currentTimeMillis() - lasttime) + "ms");
				lasttime = System.currentTimeMillis();
			}
			int size = linkBlocks.size();
			ArrayList<LinkConnection> links = new ArrayList<LinkConnection>();
			for (int i = 0; i < size - 1; i++) {
				for (int j = i + 1; j < size; j++) {
					LinkBlock a = linkBlocks.get(i);
					LinkBlock b = linkBlocks.get(j);
					if (a.sub(b) < DIFF_THRESHOULD) {
						LinkConnection link = new LinkConnection();
						link.link1 = a;
						link.link2 = b;
						links.add(link);
					}
				}
			}

			int offset = 1;
			int[][] rectMatrix = new int[mx + 3][my + 3];
			for (LinkConnection link : links) {
				rectMatrix[link.link1.x + offset][link.link1.y + offset] = 1;
				rectMatrix[link.link2.x + offset][link.link2.y + offset] = 1;
			}
			Iterator<LinkConnection> linkit = links.iterator();
			while (linkit.hasNext()) {
				LinkConnection link = linkit.next();
				if (link.link1.isLinked || link.link2.isLinked) {
					linkit.remove();
				} else {
					ArrayList<Point> route = new ArrayList<Point>();
					boolean ret = findOneRoute(mx, my, link.link1.x, link.link1.y, link.link2.x, link.link2.y, offset, rectMatrix, route);
					if (ret) {
						link.route = route;
						link.link1.isLinked = true;
						link.link2.isLinked = true;
					} else {
						linkit.remove();
					}
				}
			}
			System.out.println(links);

			for (LinkConnection link : links) {
				int cx1 = link.link1.centPoint.x + x1;
				int cy1 = link.link1.centPoint.y + y1;
				int cx2 = link.link2.centPoint.x + x1;
				int cy2 = link.link2.centPoint.y + y1;
				if (robot != null) {
					robot.mouseMove(cx1, cy1);
					robot.mousePress(InputEvent.BUTTON1_MASK);
					robot.mouseRelease(InputEvent.BUTTON1_MASK);
					robot.delay(5);
					robot.mouseMove(cx2, cy2);
					robot.mousePress(InputEvent.BUTTON1_MASK);
					robot.mouseRelease(InputEvent.BUTTON1_MASK);
					robot.delay(5);
				}
				for (int i = cx1; i < cx1 + 10; i++) {
					for (int j = cy1; j < cy1 + 10; j++) {
						bufferedImage.setRGB(i, j, ImgProcess.getRGB(255, 0, 0));
					}
				}
				for (int i = cx2; i < cx2 + 10; i++) {
					for (int j = cy2; j < cy2 + 10; j++) {
						bufferedImage.setRGB(i, j, ImgProcess.getRGB(0, 255, 0));
					}
				}

			}
			if (robot != null) {
				Iterator<Entry<String, Long>> it = userInputMap.entrySet().iterator();
				while (it.hasNext()) {
					Entry<String, Long> entry = it.next();
					if (entry.getKey().equals("click")) {
						Long by = entry.getValue();
						for (int bx = 0; bx < 7; bx++) {
							int cx = x1 + blockWidth * bx + blockWidth / 2;
							int cy = y1 + by.intValue() * blockHeight + blockHeight / 2;
							if (cy < y1 || cy > y2) {
								continue;
							}
							robot.mouseMove(cx, cy);
							robot.mousePress(InputEvent.BUTTON1_MASK);
							robot.mouseRelease(InputEvent.BUTTON1_MASK);
						}
						it.remove();
					}
				}
			}
			if (DEBUG) {
				ImageIO.write(bufferedImage, "BMP", new File("E:\\tt\\out5.bmp"));

				System.out.println((System.currentTimeMillis() - lasttime) + "ms");
				lasttime = System.currentTimeMillis();
			}
		} catch (Exception e) {
			if (!DEBUG) {
				//ImageIO.write(origBufferedImage, "BMP", new File("E:\\tt\\capturelink_" + System.currentTimeMillis() + ".png"));
			}
			throw e;
		}
	}

	public void findOneRouteTest() {
		int mx = 4;
		int my = 4;
		int x1 = 1;
		int y1 = 3;
		int x2 = 3;
		int y2 = 1;
		int offset = 1;
		int[][] rectMatrix = new int[7][7];
		rectMatrix[x1 + offset][y1 + offset] = 2;
		rectMatrix[x2 + offset][y2 + offset] = 2;
		rectMatrix[2 + offset][1 + offset] = 1;
		rectMatrix[0 + offset][2 + offset] = 1;
		ArrayList<Point> route = new ArrayList<Point>();
		boolean ret = findOneRoute(mx, my, x1, y1, x2, y2, offset, rectMatrix, route);
		System.out.println(route.size());
	}

	public boolean findOneRoute(int mx, int my, int x1, int y1, int x2, int y2, int offset, int[][] rectMatrix, ArrayList<Point> route) {
		ArrayList<Integer> direction = new ArrayList<Integer>();
		//0--change times, 1--x direction, 2-- y direction
		direction.add(0, 0);
		direction.add(1, 0);
		direction.add(2, -1);
		boolean ret = goStep(new Point(x2, y2), new Point(x2, y2 - 1), route, direction, mx, my, rectMatrix, offset, new Point(x1, y1));
		if (direction.get(0) > 2) {
			ret = false;
		}
		if (ret == false) {
			direction.set(0, 0);
			direction.set(1, 0);
			direction.set(2, 1);
			route = new ArrayList<Point>();
			ret = goStep(new Point(x2, y2), new Point(x2, y2 + 1), route, direction, mx, my, rectMatrix, offset, new Point(x1, y1));
			if (direction.get(0) > 2) {
				ret = false;
			}
			if (ret == false) {
				direction.set(0, 0);
				direction.set(1, -1);
				direction.set(2, 0);
				route = new ArrayList<Point>();
				ret = goStep(new Point(x2, y2), new Point(x2 - 1, y2), route, direction, mx, my, rectMatrix, offset, new Point(x1, y1));
				if (direction.get(0) > 2) {
					ret = false;
				}
				if (ret == false) {
					direction.set(0, 0);
					direction.set(1, 1);
					direction.set(2, 0);
					route = new ArrayList<Point>();
					ret = goStep(new Point(x2, y2), new Point(x2 + 1, y2), route, direction, mx, my, rectMatrix, offset, new Point(x1, y1));
					if (direction.get(0) > 2) {
						ret = false;
					}
				}
			}
		}
		if (ret) {
			StringBuffer sb = new StringBuffer(x2 + "," + y2 + "->");
			for (Point p : route) {
				sb.append(p.x + "," + p.y + "->");
			}
			sb.append(x1 + "," + y1);
			System.out.println(sb.toString());
		}
		return ret;
	}

	public boolean goStep(Point lastPoint, Point curPoint, ArrayList<Point> route, ArrayList<Integer> direction, int mx, int my, int[][] rectMatrix,
			int offset, Point destPoint) {
		//System.out.println(lastPoint.x + "," + lastPoint.y + "\t" + curPoint.x + "," + curPoint.y + "\t" + destPoint.x + "," + destPoint.y);
		if (curPoint.x < -1 || curPoint.x > mx + 1 || curPoint.y < -1 || curPoint.y > my + 1) {
			return false;
		}
		if (curPoint.x == destPoint.x && curPoint.y == destPoint.y) {
			return true;
		}
		if (rectMatrix[curPoint.x + offset][curPoint.y + offset] != 0) {
			return false;
		}
		if (direction.get(1) == 0 && direction.get(2) == 1) {
			route.add(curPoint);
			int lastTimes = direction.get(0);
			ArrayList<Point> newRoute = new ArrayList<Point>();
			boolean ret = goStep(curPoint, new Point(curPoint.x, curPoint.y + 1), newRoute, direction, mx, my, rectMatrix, offset, destPoint);
			if (ret == false) {
				direction.set(0, lastTimes + 1);
				if (direction.get(0) > 2) {
					return false;
				}
				direction.set(1, 1);
				direction.set(2, 0);
				lastTimes = direction.get(0);
				newRoute = new ArrayList<Point>();
				ret = goStep(curPoint, new Point(curPoint.x + 1, curPoint.y), newRoute, direction, mx, my, rectMatrix, offset, destPoint);
				if (ret == false) {
					direction.set(0, lastTimes);
					direction.set(1, -1);
					direction.set(2, 0);
					newRoute = new ArrayList<Point>();
					ret = goStep(curPoint, new Point(curPoint.x - 1, curPoint.y), newRoute, direction, mx, my, rectMatrix, offset, destPoint);
					if (ret) {
						route.addAll(newRoute);
					} else {
						direction.set(0, lastTimes);
					}
				} else {
					route.addAll(newRoute);
				}
			} else {
				route.addAll(newRoute);
			}
			return ret;
		} else if (direction.get(1) == 0 && direction.get(2) == -1) {
			route.add(curPoint);
			int lastTimes = direction.get(0);
			ArrayList<Point> newRoute = new ArrayList<Point>();
			boolean ret = goStep(curPoint, new Point(curPoint.x, curPoint.y - 1), newRoute, direction, mx, my, rectMatrix, offset, destPoint);
			if (ret == false) {
				direction.set(0, lastTimes + 1);
				if (direction.get(0) > 2) {
					return false;
				}
				direction.set(1, 1);
				direction.set(2, 0);
				lastTimes = direction.get(0);
				newRoute = new ArrayList<Point>();
				ret = goStep(curPoint, new Point(curPoint.x + 1, curPoint.y), newRoute, direction, mx, my, rectMatrix, offset, destPoint);
				if (ret == false) {
					direction.set(0, lastTimes);
					direction.set(1, -1);
					direction.set(2, 0);
					lastTimes = direction.get(0);
					newRoute = new ArrayList<Point>();
					ret = goStep(curPoint, new Point(curPoint.x - 1, curPoint.y), newRoute, direction, mx, my, rectMatrix, offset, destPoint);
					if (ret) {
						route.addAll(newRoute);
					} else {
						direction.set(0, lastTimes);
					}
				} else {
					route.addAll(newRoute);
				}
			} else {
				route.addAll(newRoute);
			}
			return ret;
		} else if (direction.get(2) == 0 && direction.get(1) == 1) {
			route.add(curPoint);
			int lastTimes = direction.get(0);
			ArrayList<Point> newRoute = new ArrayList<Point>();
			boolean ret = goStep(curPoint, new Point(curPoint.x + 1, curPoint.y), newRoute, direction, mx, my, rectMatrix, offset, destPoint);
			if (ret == false) {
				direction.set(0, lastTimes + 1);
				if (direction.get(0) > 2) {
					return false;
				}
				direction.set(1, 0);
				direction.set(2, 1);
				lastTimes = direction.get(0);
				newRoute = new ArrayList<Point>();
				ret = goStep(curPoint, new Point(curPoint.x, curPoint.y + 1), newRoute, direction, mx, my, rectMatrix, offset, destPoint);
				if (ret == false) {
					direction.set(0, lastTimes);
					direction.set(1, 0);
					direction.set(2, -1);
					newRoute = new ArrayList<Point>();
					ret = goStep(curPoint, new Point(curPoint.x, curPoint.y - 1), newRoute, direction, mx, my, rectMatrix, offset, destPoint);
					if (ret) {
						route.addAll(newRoute);
					} else {
						direction.set(0, lastTimes);
					}
				} else {
					route.addAll(newRoute);
				}
			} else {
				route.addAll(newRoute);
			}
			return ret;
		} else if (direction.get(2) == 0 && direction.get(1) == -1) {
			route.add(curPoint);
			int lastTimes = direction.get(0);
			ArrayList<Point> newRoute = new ArrayList<Point>();
			boolean ret = goStep(curPoint, new Point(curPoint.x - 1, curPoint.y), newRoute, direction, mx, my, rectMatrix, offset, destPoint);
			if (ret == false) {
				direction.set(0, lastTimes + 1);
				if (direction.get(0) > 2) {
					return false;
				}
				direction.set(1, 0);
				direction.set(2, 1);
				lastTimes = direction.get(0);
				newRoute = new ArrayList<Point>();
				ret = goStep(curPoint, new Point(curPoint.x, curPoint.y + 1), newRoute, direction, mx, my, rectMatrix, offset, destPoint);
				if (ret == false) {
					direction.set(0, lastTimes);
					direction.set(1, 0);
					direction.set(2, -1);
					newRoute = new ArrayList<Point>();
					ret = goStep(curPoint, new Point(curPoint.x, curPoint.y - 1), newRoute, direction, mx, my, rectMatrix, offset, destPoint);
					if (ret) {
						route.addAll(newRoute);
					} else {
						direction.set(0, lastTimes);
					}
				} else {
					route.addAll(newRoute);
				}
			} else {
				route.addAll(newRoute);
			}
			return ret;
		} else {
			return false;
		}

	}
}
